// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: junglekim

#include "coin2/strategy/vmm/vmm_factory.h"

namespace coin2::strategy::vmm {

std::unique_ptr<VmmPricer> CreateNewVmmPricer(
    const ::nlohmann::json& pricer_config,
    const bool& avoid_arbi,
    const bool& verbose) {
  if (pricer_config["type"] == "MultiEx") {
    return std::make_unique<VmmMultiExPricer>(pricer_config["configs"], avoid_arbi, verbose);
  } else if (pricer_config["type"] == "Chicken") {
    return std::make_unique<VmmChickenPricer>(pricer_config["configs"], avoid_arbi, verbose);
  } else if (pricer_config["type"] == "Bbo") {
    return std::make_unique<VmmBboPricer>(pricer_config["configs"], verbose);
  } else if (pricer_config["type"] == "BboReference") {
    return std::make_unique<VmmBboReferencePricer>(pricer_config["configs"], verbose);
  } else {
    NOTREACHED() << pricer_config["type"];
  }
  return nullptr;
}

std::unique_ptr<VmmOrderController> CreateNewVmmOrderController(
    const ::nlohmann::json& oc_config,
    const bool& dry_run,
    const int64_t& start_time,
    const bool& verbose) {
  if (oc_config["type"] == "Basic") {
    return std::make_unique<VmmBasicOrderController>(oc_config["configs"], dry_run, verbose);
  } else if (oc_config["type"] == "Layering") {
    return std::make_unique<VmmLayeringOrderController>(oc_config["configs"], dry_run, verbose);
  } else if (oc_config["type"] == "Smooth") {
    return std::make_unique<VmmSmoothOrderController>(oc_config["configs"], dry_run, verbose);
  } else if (oc_config["type"] == "AscendingLayering") {
    return std::make_unique<VmmAscendingLayeringOrderController>(
        oc_config["configs"],
        dry_run,
        verbose);
  } else if (oc_config["type"] == "Approach") {
    return std::make_unique<VmmApproachOrderController>(oc_config["configs"], dry_run, verbose);
  } else if (oc_config["type"] == "DeltaHedge") {
    return std::make_unique<VmmDeltaHedgeOrderController>(
        oc_config["configs"],
        dry_run,
        start_time,
        verbose);
  } else {
    NOTREACHED() << oc_config["type"];
  }
  return nullptr;
}

std::unique_ptr<VmmArbitrageur> CreateNewVmmArbitrageur(
    const ::nlohmann::json& arbi_config,
    const bool& dry_run,
    const bool& verbose) {
  std::string tag;
  if (arbi_config["type"] == "Agg") {
    tag = "AggArb";
    return std::make_unique<VmmAggArbitrageur>(
        arbi_config["params"],
        arbi_config["configs"],
        dry_run,
        tag,
        verbose);
  } else {
    NOTREACHED() << arbi_config["type"];
  }
  return nullptr;
}
}  // namespace coin2::strategy::vmm